package Ms

//
//import (
//	"database/sql"
//	"encoding/json"
//	"fmt"
//	"db2s/dataDispos"
//	"db2s/global"
//	"runtime"
//	"strconv"
//	"strings"
//)
//
//var (
//	DBType = "sqlserver"
//	vlog   string
//)
//
//func (ms TableMeta) tableColumnTypeText(s string) bool {
//	for _, v := range []string{
//		"CHAR", "VARCHAR", "NCHAR", "NVARCHAR",
//		"NUMBER", "INTEGER", "SMALLINT", "FLOAT", "FLOAT", "BINARY_FLOAT", "DOUBLE", "BINARY_DOUBLE", "DECIMAL", "BIT",
//	} {
//		if strings.HasPrefix(strings.ToUpper(s), v) {
//			return true
//		}
//	}
//	return false
//}
//
//func (ms TableMeta) stringTypeConvert(v string) string {
//	var charVal, hasPre, ps string
//	var charM = map[string]int{"CHAR": 1, "NCHAR": 1, "VARCHAR": 1, "NVARCHAR": 1}
//	if n := strings.Index(v, "("); n != -1 {
//		hasPre = v[:strings.Index(v, "(")]
//		ps = v[n+1 : strings.Index(v, ")")]
//	} else {
//		hasPre = v
//	}
//	if _, ok := charM[strings.ToUpper(hasPre)]; ok {
//		switch strings.ToUpper(hasPre) {
//		case "VARCHAR":
//			if strings.Contains(strings.ToUpper(ps), "CHAR") {
//				space := strings.TrimSpace(ps[:strings.Index(ps, "CHAR")])
//				charVal = fmt.Sprintf("VARCHAR(%s)", space)
//			} else {
//				charVal = fmt.Sprintf("VARCHAR(%s)", ps)
//			}
//		case "CHAR":
//			if strings.Contains(strings.ToUpper(ps), "CHAR") {
//				space := strings.TrimSpace(ps[:strings.Index(ps, "CHAR")])
//				charVal = fmt.Sprintf("CHAR(%s)", space)
//			} else {
//				charVal = fmt.Sprintf("CHAR(%s)", ps)
//			}
//		case "NCHAR":
//			charVal = fmt.Sprintf("CHAR(%s)", ps)
//		case "NVARCHAR":
//			charVal = fmt.Sprintf("VARCHAR(%s)", ps)
//		}
//	}
//	return charVal
//}
//
///*
//常用的有 number 和 float 类型两种，可以用它们来表示整数和小数。
//*/
//func (ms TableMeta) numberTypeConvert(v string) string {
//	var (
//		number, hasPre string
//		err            error
//	)
//	if n := strings.Index(v, "("); n != -1 {
//		hasPre = v[:strings.Index(v, "(")]
//	} else {
//		hasPre = v
//	}
//	var numberM = map[string]int{"FLOAT": 1, "INTEGER": 1, "INT": 1, "SMALLINT": 1, "REAL": 1, "BINARY_DOUBLE": 1, "BINARY_FLOAT": 1,
//		"BINARY_INTEGER": 1, "PLS_INTEGER": 1, "NATURAL": 1, "NATURALN": 1, "POSITIVE": 1, "POSITIVEN": 1, "SIGNTYPE": 1, "SIMPLE_INTEGER": 1,
//		"DECIMAL": 1, "DEC": 1, "NUMERIC": 1, "NUMBER": 1,
//	}
//	if _, ok := numberM[strings.ToUpper(hasPre)]; ok {
//		switch strings.ToUpper(hasPre) {
//		case "FLOAT": //FLOAT数据类型是NUMBER数据类型的子类型。 其主要目的是促进与ANSI SQL FLOAT数据类型的兼容,float(p)，最大精度为126，大致等于十进制数位数的38位数，P(d) = 0.30103 * P(b)
//			var p int
//			if p, err = strconv.Atoi(v[strings.Index(v, "(")+1 : strings.Index(v, ")")]); err != nil {
//				p = 0
//			}
//			f := fmt.Sprintf("%v", float64(p)*0.30103)
//			s := f[:strings.Index(f, ".")]
//			if p, err = strconv.Atoi(s); err != nil {
//				p = 0
//			}
//			number = fmt.Sprintf("float(%d)", p)
//		case "INTEGER":
//			number = "DECIMAL(38)"
//		case "INT":
//			number = "DECIMAL(38)"
//		case "SMALLINT":
//			number = "DECIMAL(38)"
//		case "REAL":
//			number = "REAL"
//		case "BINARY_DOUBLE":
//			number = "DOUBLE"
//		case "BINARY_FLOAT":
//			number = "FLOAT"
//		case "BINARY_INTEGER":
//			number = "DECIMAL(38)"
//		case "PLS_INTEGER":
//			number = "INT"
//		case "NATURAL":
//			number = "INT"
//		case "NATURALN":
//			number = "INT"
//		case "POSITIVE":
//			number = "INT"
//		case "POSITIVEN":
//			number = "INT"
//		case "SIGNTYPE":
//			number = "TINYINT"
//		case "SIMPLE_INTEGER":
//			number = "INT"
//		case "BOOLEAN":
//			number = "TINYINT(1)"
//		case "DECIMAL":
//			number = v
//		case "DEC":
//			number = "DECIMAL(40,0)"
//		case "NUMERIC":
//			number = "DECIMAL(40,0)"
//		case "NUMBER":
//			var s, e int
//			if n := strings.Index(v, "("); n != -1 {
//				s = n
//			}
//			if n := strings.Index(v, ")"); n != -1 {
//				e = n
//			}
//			if s != e && e > s {
//				if pr := v[s+1 : e]; strings.Contains(pr, "*") {
//					if strings.EqualFold(pr, "*") {
//						number = fmt.Sprintf("DECIMAL(65,30)")
//					} else {
//						number = fmt.Sprintf("DECIMAL(%s)", strings.ReplaceAll(pr, "*", "40"))
//					}
//				} else {
//					if strings.Contains(pr, ",") {
//						integer, decimal := strings.Split(pr, ",")[0], strings.Split(pr, ",")[1]
//						integerI, _ := strconv.Atoi(integer)
//						decimalI, _ := strconv.Atoi(decimal)
//						if integerI < decimalI {
//							integerI = decimalI
//						}
//						number = fmt.Sprintf("DECIMAL(%v%s%v)", integerI, ",", decimalI)
//					} else {
//						number = fmt.Sprintf("DECIMAL(%s)", pr)
//					}
//				}
//			} else {
//				number = fmt.Sprintf("DECIMAL(65,30)")
//			}
//		}
//	}
//	return number
//}
//
///*
//常用的日期类型转换。
//*/
////default to_char(sysdate,'YYYY MM DD');  --->(CURRENT_date());
//func (ms TableMeta) timeTypeConvert(v string) string {
//	var (
//		err           error
//		timeD, hasPre string
//	)
//	datePre := map[string]int{"SYSDATE": 1, "DATE": 1, "TIMESTAMP": 1, "TIMESTAMP WITH TIME ZONE": 1, "TIMESTAMP WITH LOCAL TIME ZONE": 1, "INTERVAL YEAR TO MOTH": 1, "INTERVAL DAY TO SECOND": 1, "TO_CHAR(SYSDATE,'YYYYMMDD')": 1}
//	if n := strings.Index(v, "("); n != -1 {
//		hasPre = v[:strings.Index(v, "(")]
//	} else {
//		hasPre = v
//	}
//	if _, ok := datePre[strings.ToUpper(hasPre)]; ok {
//		switch strings.ToUpper(hasPre) {
//		case "SYSDATE":
//			timeD = "CURRENT_TIMESTAMP"
//		case "DATE":
//			timeD = "DATETIME"
//		case "TIMESTAMP":
//			timeD = "DATETIME"
//			var s, e, p int
//			if n := strings.Index(v, "("); n != -1 {
//				s = n
//			}
//			if n := strings.Index(v, ")"); n != -1 {
//				e = n
//			}
//			if s != e {
//				if p, err = strconv.Atoi(v[s+1 : e]); err != nil {
//					p = 10
//				} else {
//					if p > 6 {
//						p = 6
//					}
//				}
//			}
//			if p > 0 {
//				timeD = fmt.Sprintf("DATETIME(%d)", p)
//			} else {
//				timeD = fmt.Sprintf("DATETIME")
//			}
//		case "TIMESTAMP WITH TIME ZONE":
//			timeD = fmt.Sprintf("DATETIME(6)")
//		case "TIMESTAMP WITH LOCAL TIME ZONE":
//			timeD = fmt.Sprintf("DATETIME(6)")
//		}
//
//	}
//	return timeD
//}
//
///*
//常用的文本类型转换。
//long {可变长字符列，最大长度限制是2GB，用于不需要作字符串搜索的长串数据，如果要进行字符搜索就要用varchar2类型。long是一种较老的数据类型，将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。}
//blob\clob\nclob {三种大型对象(LOB)，用来保存较大的图形文件或带格式的文本文件，如Word文档，以及音频、视频等非文本文件，最大长度是4GB。LOB有几种类型，取决于你使用的字节的类型，Oracle 8i实实在在地将这些数据存储在数据库内部保存。可以执行读取、存储、写入等特殊操作。}
//*/
//func (ms TableMeta) textTypeConvert(v string) string {
//	var lobD, hasPre string
//	datePre := map[string]int{"CLOB": 1, "LONG": 1, "NCLOB": 1}
//	if n := strings.Index(v, "("); n != -1 {
//		hasPre = v[:strings.Index(v, "(")]
//	} else {
//		hasPre = v
//	}
//	if _, ok := datePre[strings.ToUpper(hasPre)]; ok {
//		switch strings.ToUpper(hasPre) {
//		case "LONG":
//			lobD = "LONGTEXT"
//		case "CLOB":
//			lobD = "LONGTEXT"
//		case "NCLOB":
//			lobD = "LONGTEXT"
//		case "BLOB":
//			lobD = "LONGBLOB"
//		}
//
//	}
//	return lobD
//}
//
///*
//常用的二进制类型转换。
//*/
//func (ms TableMeta) binyTypeConvert(v string) string {
//	var binyD, haspre string
//	datePre := map[string]int{"BLOB": 1, "LONG RAW": 1, "RAW": 1}
//	if n := strings.Index(v, "("); n != -1 {
//		haspre = v[:strings.Index(v, "(")]
//	} else {
//		haspre = v
//	}
//	if _, ok := datePre[strings.ToUpper(haspre)]; ok {
//		switch strings.ToUpper(haspre) {
//		case "BLOB":
//			binyD = "LONGBLOB"
//		case "LONG RAW":
//			binyD = "LONGBLOB"
//		case "RAW":
//			binyD = "VARBINARY"
//		}
//	}
//	return binyD
//}
//
///*
//TableColumnTypeConvert Oracle 针对列的属性做映射（列的数据类型）
//*/
//func (ms TableMeta) TableColumnTypeConvert(convertData []string, logThreadSeq int64) []string {
//	var (
//		event    = "[TableColumnTypeConvert]"
//		convertS []string
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) %v %v Start table %v.%v column type conversion", logThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	global.Wlog.Debug(vlog)
//	charPre := map[string]int{"VARCHAR2": 1, "CHAR": 1, "NCHAR": 1, "ROWID": 1, "VARCHAR": 1, "NVARCHAR2": 1}
//	numberPre := map[string]int{"FLOAT": 1, "INTEGER": 1, "INT": 1, "SMALLINT": 1, "REAL": 1, "BINARY_DOUBLE": 1, "BINARY_FLOAT": 1,
//		"BINARY_INTEGER": 1, "PLS_INTEGER": 1, "NATURAL": 1, "NATURALN": 1, "POSITIVE": 1, "POSITIVEN": 1, "SIGNTYPE": 1, "SIMPLE_INTEGER": 1,
//		"DECIMAL": 1, "DEC": 1, "NUMERIC": 1, "NUMBER": 1,
//	}
//	datePre := map[string]int{"SYSDATE": 1, "DATE": 1, "TIMESTAMP": 1, "TIMESTAMP WITH TIME ZONE": 1, "TIMESTAMP WITH LOCAL TIME ZONE": 1, "INTERVAL YEAR TO MOTH": 1, "INTERVAL DAY TO SECOND": 1}
//	textPre := map[string]int{"CLOB": 1, "LONG": 1, "NCLOB": 1}
//	binPre := map[string]int{"BLOB": 1, "LONG RAW": 1, "RAW": 1}
//	var vb string
//	for _, v := range convertData {
//		vb = v
//		if n := strings.Index(v, "("); n != -1 {
//			vb = v[:strings.Index(v, "(")]
//		}
//		if _, ok := charPre[strings.ToUpper(vb)]; ok {
//			convertS = append(convertS, ms.stringTypeConvert(v))
//		} else if _, ok = numberPre[strings.ToUpper(vb)]; ok {
//			convertS = append(convertS, ms.numberTypeConvert(v))
//		} else if _, ok = datePre[strings.ToUpper(vb)]; ok {
//			convertS = append(convertS, ms.timeTypeConvert(v))
//		} else if _, ok = textPre[strings.ToUpper(vb)]; ok {
//			convertS = append(convertS, ms.textTypeConvert(v))
//		} else if _, ok = binPre[strings.ToUpper(vb)]; ok {
//			convertS = append(convertS, ms.binyTypeConvert(v))
//		} else {
//			convertS = append(convertS, v)
//		}
//	}
//	vlog = fmt.Sprintf("(%d) %v %v Column type conversion of table %v.%v is completed.", logThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	global.Wlog.Debug(vlog)
//	return convertS
//}
//
//func (ms TableMeta) DatabaseNameList(db *sql.DB, checkSchema map[string]int) (map[string]int, error) {
//	var (
//		A           = make(map[string]int)
//		event       = "[DatabaseNameList]"
//		tableData   []map[string]interface{}
//		strSql      string
//		schema      string
//		tableList   []string
//		tableJoin   string
//		execTimeout int64
//		err         error
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	vlog = fmt.Sprintf("(%d) %v %v Start querying database table information.", ms.LogThreadSeq, callFuncInfo, event)
//	global.Wlog.Debug(vlog)
//	for k := range checkSchema {
//		schema = strings.Split(k, global.SchemaTableSplist)[0]
//		tableList = append(tableList, fmt.Sprintf("object_id('%v')", strings.ReplaceAll(k, global.SchemaTableSplist, ".")))
//	}
//	if len(tableList) > 0 {
//		tableJoin = fmt.Sprintf("where object_id in (%v)", strings.Join(tableList, ","))
//	}
//	if !ms.LowerCaseTableNames {
//		strSql = fmt.Sprintf("select (UPPER('%v') + '%s' + UPPER(name)) as tableName from sys.tables  %v ", schema, global.SchemaTableSplist, tableJoin)
//	} else {
//		strSql = fmt.Sprintf("select ('%v' + '%s' + name) as tableName from sys.tables  %v", schema, global.SchemaTableSplist, tableJoin)
//	}
//	global.Wlog.Debug(fmt.Sprintf("(%d) %s begin query table name list, exec sql is %v", ms.LogThreadSeq, event, strSql))
//	active := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = active.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		tableData = f1.([]map[string]interface{})
//	}
//	for i := range tableData {
//		A[fmt.Sprintf("%v", tableData[i]["tableName"])]++
//	}
//	vlog = fmt.Sprintf("(%d) %v %v Database table information query completed. reslult is {%v}", ms.LogThreadSeq, callFuncInfo, event, A)
//	global.Wlog.Debug(vlog)
//	return A, nil
//}
//func (ms TableMeta) TableColumnName1(db *sql.DB, schema, table string, logThreadSeq int64) ([]map[string]interface{}, error) {
//	var (
//		event             = "[TableColumnName1]"
//		execTimeout       int64
//		err               error
//		tableC, tableData []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) %v %v Start querying table column names.", logThreadSeq, callFuncInfo, event)
//	global.Wlog.Debug(vlog)
//	strSql := fmt.Sprintf("select tc.column_name as \"columnName\",tc.data_type as \"dataType\",tc.DATA_PRECISION as \"dataPrecision\",tc.DATA_SCALE as \"dataScale\", tc.CHAR_LENGTH as \"charLength\",NULLABLE as \"isNull\",'' as \"charset\",'' as \"collationName\",to_nchar(cc.comments) as \"columnComment\",DATA_DEFAULT as \"columnDefault\" from all_tab_columns tc join all_col_comments cc on tc.OWNER = cc.owner and tc.TABLE_NAME = cc.table_name and tc.COLUMN_NAME = cc.column_name WHERE tc.owner = '%s' and tc.table_name = '%s' order by tc.COLUMN_ID", schema, table)
//	active := dataDispos.InstanceActiveS{DBType: DBType, LogThreadSeq: logThreadSeq, Event: event, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = active.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		tableData = f1.([]map[string]interface{})
//	}
//	for _, v := range tableData {
//		var f = make(map[string]interface{})
//		if fmt.Sprintf("%v", v["charLength"]) == "0" {
//			if fmt.Sprintf("%v", v["dataPrecision"]) == "<nil>" {
//				switch fmt.Sprintf("%v", v["dataScale"]) {
//				case "0":
//					f["columnType"] = fmt.Sprintf("%v", v["dataType"])
//				case "<nil>":
//					f["columnType"] = fmt.Sprintf("%v", v["dataType"])
//				default:
//					dd := fmt.Sprintf("%s", v["dataType"])
//					bed := strings.Index(dd, "(")
//					end := strings.Index(dd, ")")
//					if fmt.Sprintf("%s", v["dataScale"]) == dd[bed+1:end] {
//						f["columnType"] = fmt.Sprintf("%v", v["dataType"])
//					} else {
//						f["columnType"] = fmt.Sprintf("%v(%v)", v["dataType"], v["dataScale"])
//					}
//				}
//			} else {
//				switch fmt.Sprintf("%v", v["dataScale"]) {
//				case "<nil>":
//					f["columnType"] = fmt.Sprintf("%v(%v)", v["dataType"], v["dataPrecision"])
//				case "0":
//					f["columnType"] = fmt.Sprintf("%v(%v)", v["dataType"], v["dataPrecision"])
//				default:
//					f["columnType"] = fmt.Sprintf("%v(%v,%v)", v["dataType"], v["dataPrecision"], v["dataScale"])
//				}
//			}
//		} else {
//			f["columnType"] = fmt.Sprintf("%v(%v)", v["dataType"], v["charLength"])
//		}
//		f["charset"] = fmt.Sprintf("%v", v["charset"])
//		f["collationName"] = fmt.Sprintf("%v", v["collationName"])
//		f["columnComment"] = fmt.Sprintf("%v", v["columnComment"])
//		if strings.EqualFold(fmt.Sprintf("%v", v["columnDefault"]), "") || strings.EqualFold(fmt.Sprintf("%v", v["columnDefault"]), "''") {
//			f["columnDefault"] = "NULL"
//		} else {
//			ffs := strings.TrimSpace(fmt.Sprintf("%v", v["columnDefault"]))
//			if strings.HasPrefix(ffs, "(") && strings.HasSuffix(ffs, ")") {
//				ffs = ffs[1 : len(ffs)-1]
//			}
//			f["columnDefault"] = ffs
//			if ms.tableColumnTypeText(fmt.Sprintf("%v", f["columnType"])) && !strings.HasPrefix(ffs, "'") && !strings.EqualFold(ffs, "null") {
//				f["columnDefault"] = fmt.Sprintf("'%v'", ffs)
//			}
//		}
//		f["columnName"] = fmt.Sprintf("%v", v["columnName"])
//		switch fmt.Sprintf("%v", v["isNull"]) {
//		case "Y":
//			f["isNull"] = fmt.Sprintf("%v", "YES")
//		case "N":
//			f["isNull"] = fmt.Sprintf("%v", "NO")
//		}
//		tableC = append(tableC, f)
//	}
//	vlog = fmt.Sprintf("(%d) %v %v table column information query completed. reslult is {%v}", ms.LogThreadSeq, callFuncInfo, event, tableData)
//	global.Wlog.Debug(vlog)
//	return tableC, err
//}
//
///*
//TableIndexColumn 查询Oracle库下指定表的索引统计信息
//*/
//func (ms TableMeta) TableIndexColumn(db *sql.DB, schema string, table []string) ([]global.IndexColumn, error) {
//	var (
//		event                       = "[TableIndexColumn]"
//		tableJoin                   string
//		indexColumnData             []global.IndexColumn
//		execTimeout                 int64
//		err                         error
//		tableUnique, tableExistUniq = make(map[string]int), make(map[string]int)
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	for _, v := range table {
//		tableUnique[strings.ToUpper(v)]++
//	}
//	var objectId []string
//	for _, v := range table {
//		objectId = append(objectId, fmt.Sprintf("object_id('%v.%v')", schema, v))
//	}
//	if len(objectId) > 0 {
//		tableJoin = strings.Join(objectId, ",")
//	}
//	strSql := fmt.Sprintf("SELECT p.databaseName as databaseName,p.tableName as tableName,c.COLUMN_NAME as columnName,c.DATA_TYPE AS columnType, CAST(t.cardinality AS VARCHAR(10)) as cardinality,CAST(p.columnKey AS VARCHAR(10)) as columnKey,CAST(p.nonUnique AS VARCHAR(10)) as nonUnique,p.IndexName as indexName,CAST(p.IndexSeq AS VARCHAR(10)) as IndexSeq,CAST(c.ORDINAL_POSITION AS VARCHAR(10)) as columnSeq FROM (SELECT DB_NAME() AS databaseName,t.name AS tableName,i.is_unique AS nonUnique,i.name AS IndexName,i.index_id AS IndexSeq,i.object_id AS objectId,i.is_primary_key AS columnKey FROM sys.indexes i LEFT JOIN sys.tables t ON i.object_id = t.object_id WHERE t.object_id in (%v)) p left join sys.index_columns ic on p.objectId = ic.object_id and p.IndexSeq = ic.index_id left join (SELECT OBJECT_NAME(s.object_id) AS TableName,i.name AS IndexName,s.name AS StatisticsName,AVG(sps.DISTINCT_RANGE_ROWS) AS cardinality  FROM sys.stats s CROSS APPLY sys.dm_db_stats_histogram(s.object_id, s.stats_id) sps INNER JOIN sys.indexes i ON s.object_id = i.object_id AND s.stats_id = i.index_id WHERE s.object_id in (%v) AND sps.DISTINCT_RANGE_ROWS > 0 GROUP BY OBJECT_NAME(s.object_id), i.name, s.name) t on t.IndexName = p.IndexName left join INFORMATION_SCHEMA.COLUMNS c on p.databaseName = c.TABLE_CATALOG and p.tableName = c.TABLE_NAME and c.ORDINAL_POSITION = ic.column_id ORDER BY p.IndexSeq,c.ORDINAL_POSITION", tableJoin, tableJoin)
//	vlog = fmt.Sprintf("(%d) %v %v Table %v.%v starts querying index column information.", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	global.Wlog.Debug(vlog)
//	active := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = active.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		for _, v := range f1.([]map[string]interface{}) {
//			var dd = global.IndexColumn{}
//			jsonData, err1 := json.Marshal(v)
//			if err1 != nil {
//				vlog = fmt.Sprintf("(%d) %v %s map[string]interfacle strconv json fail. map data is {%v} err info is {%v}", ms.LogThreadSeq, callFuncInfo, event, v, err1)
//				global.Wlog.Error(vlog)
//				return nil, err1
//			}
//			// 反序列化JSON字符串到结构体
//			err = json.Unmarshal(jsonData, &dd)
//			if err != nil {
//				vlog = fmt.Sprintf("(%d) %v %s json strconv struct fail. json data is {%v} err info is {%v}", ms.LogThreadSeq, callFuncInfo, event, string(jsonData), err)
//				global.Wlog.Error(vlog)
//				return nil, err
//			}
//			vlog = fmt.Sprintf("(%d) %v %s The data query on the index column of table a is completed. result is %v", ms.LogThreadSeq, callFuncInfo, event, dd)
//			global.Wlog.Debug(vlog)
//			tableExistUniq[strings.ToUpper(dd.Table)]++
//			indexColumnData = append(indexColumnData, dd)
//		}
//	} else {
//	}
//	vlog = fmt.Sprintf("(%d) %v %s Table index column data query completed. result is {%v}", ms.LogThreadSeq, callFuncInfo, event, indexColumnData)
//	global.Wlog.Debug(vlog)
//	return indexColumnData, err
//}
//
///*
//GlobalAccessPri Oracle 查看当前用户是否有全局变量
//*/
//func (ms TableMeta) GlobalAccessPri(db *sql.DB) (bool, error) {
//	var (
//		globalPri     = make(map[string]int)
//		event         = "[GlobalAccessPri]"
//		execTimeout   int64
//		err           error
//		globalDynamic []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) %v %v The permissions that the current %s DB needs to check is message {%v}, to check it...", ms.LogThreadSeq, callFuncInfo, event, DBType, globalPri)
//	global.Wlog.Debug(vlog)
//	globalPri["SELECT ANY DICTIONARY"] = 0
//	var globalPriS []string
//	for k := range globalPri {
//		globalPriS = append(globalPriS, k)
//	}
//	//查找全局权限 类似于grant all privileges on *.* 或 grant select on *.*
//	vlog = fmt.Sprintf("(%d) %v %v  Query the current %s DB global dynamic grants permission, to query it...", ms.LogThreadSeq, callFuncInfo, event, DBType)
//	global.Wlog.Debug(vlog)
//	strSql := fmt.Sprintf("select PRIVILEGE as \"privileges\" from user_sys_privs where PRIVILEGE IN ('%s')", strings.Join(globalPriS, "','"))
//	active := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = active.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return false, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		globalDynamic = f1.([]map[string]interface{})
//	}
//
//	//权限缺失列表
//	if len(globalDynamic) == 0 {
//		strSql = fmt.Sprintf("SELECT PRIVILEGE as \"privileges\" FROM ROLE_SYS_PRIVS WHERE PRIVILEGE IN ('%s') group by PRIVILEGE", strings.Join(globalPriS, "','"))
//		if execTimeout, f1, err = active.SqlQuery(strSql, dataDispos.SMap); err != nil {
//			vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//			global.Wlog.Error(vlog)
//			return false, err
//		}
//		if f1 != nil {
//			globalDynamic = f1.([]map[string]interface{})
//		}
//		vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//		global.Wlog.Debug(vlog)
//	}
//	for _, gd := range globalDynamic {
//		if _, ok := globalPri[strings.ToUpper(fmt.Sprintf("%s", gd["privileges"]))]; ok {
//			delete(globalPri, strings.ToUpper(fmt.Sprintf("%s", gd["privileges"])))
//		}
//	}
//	if len(globalPri) == 0 {
//		vlog = fmt.Sprintf("(%d) %v %v The current global access user with permission to connect to %s DB is normal and can be verified normally...", ms.LogThreadSeq, callFuncInfo, event, DBType)
//		global.Wlog.Debug(vlog)
//		return true, nil
//	}
//	if _, ok := globalPri["SELECT ANY DICTIONARY"]; !ok {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return false, nil
//	}
//	return true, nil
//}
//
///*
//TableAccessPriCheck Oracle 查询用户是否有表的查询权限
//*/
//func (ms TableMeta) TableAccessPriCheck(db *sql.DB, checkTableList []string, dateFix string) (map[string]int, error) {
//	var (
//		globalPri, globalPriAllTab = make(map[string]int), make(map[string]int)
//		newCheckTableList          = make(map[string]int)
//		A                          = make(map[string]int)
//		PT, abPT                   = make(map[string]int), make(map[string]int)
//		event                      = "[TableAccessPriCheck]"
//		execTimeout                int64
//		err                        error
//		globalDynamic, tablePri    []map[string]interface{}
//		columnMerge                = func(AC []map[string]interface{}, F1 ...string) map[string][]string {
//			var cc = make(map[string][]string)
//			var N, E string
//			var dd []string
//			for _, C := range AC {
//				if len(F1) == 1 {
//					E = fmt.Sprintf("%s", F1)
//				} else {
//					E = fmt.Sprintf("%s", C[F1[0]])
//				}
//				if E != N {
//					N = E
//					dd = []string{}
//					if len(F1) == 1 {
//						dd = append(dd, strings.ToUpper(fmt.Sprintf("%s", C[F1[0]])))
//					} else {
//						dd = append(dd, strings.ToUpper(fmt.Sprintf("%s", C[F1[1]])))
//					}
//				} else {
//					if len(F1) == 1 {
//						dd = append(dd, strings.ToUpper(fmt.Sprintf("%s", C[F1[0]])))
//					} else {
//						dd = append(dd, strings.ToUpper(fmt.Sprintf("%s", C[F1[1]])))
//					}
//				}
//				cc[N] = dd
//			}
//			return cc
//		}
//		priAllTableS []string
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	globalPri["SELECT"] = 0
//	globalPriAllTab["SELECT ANY TABLE"] = 0
//	if strings.ToUpper(dateFix) == "TABLE" {
//		globalPri["INSERT"] = 0
//		globalPriAllTab["INSERT ANY TABLE"] = 0
//		globalPri["DELETE"] = 0
//		globalPriAllTab["DELETE ANY TABLE"] = 0
//	}
//	for k := range globalPriAllTab {
//		priAllTableS = append(priAllTableS, k)
//	}
//	vlog = fmt.Sprintf("(%d) %v %v The permissions that the current %v DB needs to check is message {%v},check table list is {%v}. to check it...", ms.LogThreadSeq, callFuncInfo, event, DBType, globalPri, newCheckTableList)
//	global.Wlog.Debug(vlog)
//
//	//针对要校验的库做去重（库级别的）
//	//校验库.表由切片改为map
//	for _, AA := range checkTableList {
//		newCheckTableList[AA]++
//	}
//	//vlog = fmt.Sprintf("(%d) The current Oracle DB needs to check the permission table is message {%v}, to check it...", logThreadSeq, newCheckTableList)
//	//global.Wlog.Debug(vlog)
//	//校验库做去重处理
//	for _, aa := range checkTableList {
//		if strings.Contains(aa, ".") {
//			A[strings.Split(aa, ".")[0]]++
//			if !ms.LowerCaseTableNames {
//				A[strings.ToUpper(strings.Split(aa, ".")[0])]++
//			}
//		}
//	}
//	fmt.Println("----oracle---2:", A)
//	//处理oracle用户角色，该用户角色拥有insert、select 、delete any table的权限
//	//查找全局权限 类似于grant all privileges on *.* 或 grant select on *.*
//	vlog = fmt.Sprintf("(%d) %v %v Query the current %s DB global dynamic grants permission, to query it...", ms.LogThreadSeq, callFuncInfo, event, DBType)
//	global.Wlog.Debug(vlog)
//	strSql := fmt.Sprintf("SELECT PRIVILEGE as \"privileges\" FROM ROLE_SYS_PRIVS WHERE PRIVILEGE IN ('%s') group by PRIVILEGE", strings.Join(priAllTableS, "','"))
//	fmt.Println("----oracle---3:", strSql)
//	global.Wlog.Debug(fmt.Sprintf("(%d) %v %v Query the current %s DB global dynamic grants permission. SQL info is %s", ms.LogThreadSeq, callFuncInfo, event, DBType, strSql))
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		globalDynamic = f1.([]map[string]interface{})
//	}
//	fmt.Println("----oracle---4:", globalDynamic)
//	//该用户有权限角色设置
//	if len(globalDynamic) != 0 {
//		A = globalPriAllTab
//		CC := columnMerge(globalDynamic, "privileges")
//		fmt.Println("-----oracle--5:", CC, A)
//		for _, v := range CC {
//			var aaseq int
//			for _, vi := range v {
//				if _, ok := A[fmt.Sprintf("%s", vi)]; ok {
//					aaseq++
//				}
//			}
//			if len(A) == aaseq {
//				vlog = fmt.Sprintf("(%d) %v %v The %s DB table information that meets the permissions and needs to be verified is {%v}...", ms.LogThreadSeq, callFuncInfo, event, DBType, newCheckTableList)
//				global.Wlog.Debug(vlog)
//				return newCheckTableList, nil
//			}
//		}
//		//权限缺失列表
//		for _, v := range CC {
//			for _, vi := range v {
//				if _, ok := A[fmt.Sprintf("%s", vi)]; ok {
//					delete(globalPriAllTab, vi)
//				}
//			}
//		}
//		fmt.Println("-----oracle--6:", globalPriAllTab)
//	}
//
//	//查询当前表的权限
//	//类似于grant all privileges on pcms.a 或 grant select on pcms.a
//	vlog = fmt.Sprintf("(%d) %s %v Query the current %s DB global dynamic table permission, to query it...", ms.LogThreadSeq, callFuncInfo, event, DBType)
//	global.Wlog.Debug(vlog)
//	//遍历没有schema pri权限的剩余库
//	var DM = make(map[string]int)
//	for _, D := range checkTableList {
//
//		DM[D]++
//		if !ms.LowerCaseTableNames {
//			DM[strings.ToUpper(D)]++
//		}
//	}
//	fmt.Println("-----oracle--7:", DM)
//	strSql = fmt.Sprintf("select owner||'.'||table_name AS \"tablesName\",PRIVILEGE as \"privileges\" from user_tab_privs")
//	fmt.Println("-----oracle--8:", strSql)
//	if execTimeout, f1, err = dispos.SqlQuery(strSql, dataDispos.SMap); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strSql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strSql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		tablePri = f1.([]map[string]interface{})
//	}
//	DD := columnMerge(tablePri, "tablesName", "privileges")
//	fmt.Println("-----oracle--9:", DD)
//	for K, V := range DD {
//		var aaaseq int
//		if !ms.LowerCaseTableNames {
//			strings.ToUpper(K)
//		}
//		fmt.Println("----oracle--10:", K, V)
//		fmt.Println("----oracle--11:", DM[K])
//		if _, ok := DM[K]; ok {
//			for _, vi := range V {
//				fmt.Println("----oracle--12:", vi)
//				fmt.Println("----oracle--13:", globalPriAllTab[fmt.Sprintf("%s ANY TABLE", strings.ToUpper(vi))])
//				fmt.Println("----oracle--14:", globalPri[fmt.Sprintf("%s", strings.ToUpper(vi))])
//				if _, ok1 := globalPriAllTab[fmt.Sprintf("%s ANY TABLE", strings.ToUpper(vi))]; ok1 {
//					aaaseq++
//				} else if _, ok2 := globalPri[fmt.Sprintf("%s", strings.ToUpper(vi))]; ok2 {
//					aaaseq++
//				}
//			}
//		}
//		fmt.Println("-----oracle---15:", aaaseq)
//		if aaaseq == len(globalPriAllTab) {
//			PT[K]++
//		} else {
//			abPT[K]++
//		}
//	}
//	if len(PT) == 0 {
//		vlog = fmt.Sprintf("(%d) %v %v The current table %s.%s in %s DB lacks some rights restrictions, please check the rights related to the table %s.%s {%v}", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table, DBType, ms.Schema, ms.Table, globalPri)
//		global.Wlog.Error(vlog)
//		return nil, nil
//	}
//	vlog = fmt.Sprintf("(%d) %v %v The %s DB table information that needs to be verified to meet the permissions is {%v}, and the information that is not satisfied is {%v}...", ms.LogThreadSeq, callFuncInfo, event, DBType, PT, abPT)
//	global.Wlog.Debug(vlog)
//	return PT, nil
//}
//
///*
//TableAllColumn Oracle 获取校验表的列信息，包含列名，列序号，列类型
//*/
//func (ms TableMeta) TableAllColumn(db *sql.DB, tableName map[string]int) (tableData map[string][]global.TableMeta, err error) {
//	var (
//		event         = "[TableAllColumn]"
//		execTimeout   int64
//		schemaJoin    string
//		tableJoin     string
//		schema, table []string
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) %v %v Start querying column attribute information of table %v.%v", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	global.Wlog.Debug(vlog)
//
//	for k := range tableName {
//		vl := strings.Split(k, global.SchemaTableSplist)
//		schema = append(schema, vl[0])
//		table = append(table, vl[1])
//	}
//	if len(table) > 0 {
//		tableJoin = fmt.Sprintf(" and TABLE_NAME in ('%s')", strings.Join(table, "','"))
//	}
//	if len(schema) > 0 {
//		schemaJoin = fmt.Sprintf("where table_schema in ('%s')", strings.Join(schema, "','"))
//	}
//	var strsql string
//	if !ms.LowerCaseTableNames {
//		strsql = fmt.Sprintf("SELECT UPPER(table_schema) AS databaseName, UPPER(table_name) AS tableName,column_name AS columnName, CASE WHEN data_type = 'decimal' AND NUMERIC_SCALE IS NOT NULL THEN data_type + '(' + CAST(NUMERIC_PRECISION AS VARCHAR) + ',' + CAST(NUMERIC_SCALE AS VARCHAR) + ')' WHEN data_type IN ('varchar', 'nvarchar') AND character_maximum_length IS NOT NULL THEN data_type + '(' + CAST(character_maximum_length AS VARCHAR) + ')' ELSE data_type END AS dataType, CAST(ordinal_position AS varchar)  AS columnSeq, is_nullable AS isNull FROM INFORMATION_SCHEMA.COLUMNS %v %v order by ordinal_position", schemaJoin, tableJoin)
//	} else {
//		strsql = fmt.Sprintf("SELECT table_schema AS databaseName,  table_name AS tableName,column_name AS columnName, CASE WHEN data_type = 'decimal' AND NUMERIC_SCALE IS NOT NULL THEN data_type + '(' + CAST(NUMERIC_PRECISION AS VARCHAR) + ',' + CAST(NUMERIC_SCALE AS VARCHAR) + ')' WHEN data_type IN ('varchar', 'nvarchar') AND character_maximum_length IS NOT NULL THEN data_type + '(' + CAST(character_maximum_length AS VARCHAR) + ')' ELSE data_type END AS dataType, CAST(ordinal_position AS varchar)  AS columnSeq, is_nullable AS isNull FROM INFORMATION_SCHEMA.COLUMNS %v %v order by ordinal_position", schemaJoin, tableJoin)
//	}
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", ms.LogThreadSeq, callFuncInfo, event, strsql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		tableData = make(map[string][]global.TableMeta)
//		for _, v := range f1.([]map[string]interface{}) {
//			var m = global.TableMeta{}
//			jsonData, err1 := json.Marshal(v)
//			if err1 != nil {
//				vlog = fmt.Sprintf("(%d) %v %s map[string]interfacle strconv json fail. map data is {%v} err info is {%v}", ms.LogThreadSeq, callFuncInfo, event, v, err1)
//				global.Wlog.Error(vlog)
//				return nil, err1
//			}
//			err = json.Unmarshal(jsonData, &m)
//			if err != nil {
//				vlog = fmt.Sprintf("(%d) %v %s json strconv struct fail. json data is {%v} err info is {%v}", ms.LogThreadSeq, callFuncInfo, event, string(jsonData), err1)
//				global.Wlog.Error(vlog)
//				return nil, err
//			}
//			key := fmt.Sprintf("%s%s%s", m.DatabaseName, global.SchemaTableSplist, m.TableName)
//			if l, ok := tableData[key]; ok {
//				tableData[key] = append(l, m)
//			} else {
//				tableData[key] = []global.TableMeta{m}
//			}
//		}
//	}
//	vlog = fmt.Sprintf("(%d) %v %s Query of column attribute information of table a is completed. result is {%v}", ms.LogThreadSeq, callFuncInfo, event, tableData)
//	global.Wlog.Debug(vlog)
//	return
//}
//func (ms TableMeta) TableDistribution(_ *sql.DB, schema string, table []string) (f []map[string]interface{}, err error) {
//	var (
//		event       = "[TableDistribution]"
//		execTimeout int64
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	vlog = fmt.Sprintf("(%d) %v %v Start querying the distribution of table %v.%v", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	global.Wlog.Debug(vlog)
//	for _, v := range table {
//		f = append(f, map[string]any{"tableName": fmt.Sprintf("%s.%s", schema, v), "shardMode": "NORMAL", "shardName": "single"})
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, "no sql", execTimeout)
//	global.Wlog.Debug(vlog)
//	vlog = fmt.Sprintf("(%d) %v %v The distribution query of table %v.%v is completed. result is {%v}", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table, f)
//	global.Wlog.Debug(vlog)
//	return
//}
//
//// 一个索引的包含的列类型对比
//func (ms TableMeta) typeSelection(tsl []global.IndexColumn) []int {
//	var typeDefinition = map[string]int{"int": 1, "time": 2, "string": 3, "text": 4}
//	var intType = []string{"NUMBER", "INTEGER", "FLOAT", "REAL", "DOUBLE", "DECIMAL", "BINARY_FLOAT", "BINARY_DOUBLE"}
//	var timeType = []string{"DATE", "TIMESTAMP", "INTERVAL YEAR", "INTERVAL DAY"}
//	var stringType = []string{"CHAR", "VARCHAR2", "NCHAR", "NVARCHAR2"}
//	var typeSeq []int
//	for k, v := range tsl {
//		//前导列限制，后期可以放开
//		if k > 0 {
//			continue
//		}
//		var exist = false
//		for _, v1 := range intType {
//			if strings.HasPrefix(strings.ToUpper(v.ColumnType), v1) {
//				typeSeq = append(typeSeq, typeDefinition["int"])
//				exist = true
//			}
//		}
//		for _, v1 := range timeType {
//			if strings.HasPrefix(strings.ToUpper(v.ColumnType), v1) {
//				typeSeq = append(typeSeq, typeDefinition["time"])
//				exist = true
//			}
//		}
//		for _, v1 := range stringType {
//			if strings.HasPrefix(strings.ToUpper(v.ColumnType), v1) {
//				typeSeq = append(typeSeq, typeDefinition["string"])
//				exist = true
//			}
//		}
//		if !exist {
//			typeSeq = append(typeSeq, 100)
//		}
//	}
//	return typeSeq
//}
//
//// 多个索引的数据类型比较，按照规则选择一个或多个相同的
//func (ms TableMeta) typeSum(ll map[string][]int) (iname string) {
//	ivalue := 10000
//	var islice []int
//	for k, v := range ll {
//		var isum int
//		for _, v1 := range v {
//			isum += v1
//		}
//		if isum < ivalue {
//			iname = k
//			islice = v
//			ivalue = isum
//		} else if isum == ivalue {
//			for k2, v2 := range islice {
//				if v2 < v[k2] {
//					iname = k
//					islice = v
//					ivalue = isum
//				}
//			}
//		}
//	}
//	return
//}
//
//// mulCardinality 普通索引通过离散度来进行筛选
//func (ms TableMeta) mulCardinality(mulSelection map[string] /*indexType*/ []string /*indexName*/, i global.IndexMerge) any {
//	//先检查索引前导列的离散度（第一列离散度值，默认选择一个离散度最高的，如果离散度比较低，建议先analyze table一下）
//	var cardinality uint64 = 0
//	event := "[mulCardinality]"
//	var indexName string
//	if len(mulSelection) == 0 {
//		return nil
//	}
//	for _, v := range mulSelection {
//		for _, v1 := range v {
//			var curryIndexCardinality uint64 = 0
//			for _, v2 := range i.IndexColumn[v1] {
//				if parseUint, err2 := strconv.ParseUint(v2.Cardinality, 10, 64); err2 != nil {
//					global.Wlog.Error(fmt.Sprintf("(%d) %s string strconv uint64 fail. string is {%v}, error info is %v", ms.LogThreadSeq, event, v2.Cardinality, err2))
//				} else {
//					if parseUint > curryIndexCardinality {
//						curryIndexCardinality = parseUint
//					}
//				}
//			}
//			if curryIndexCardinality > cardinality {
//				cardinality = curryIndexCardinality
//				indexName = v1
//			}
//		}
//	}
//	return map[string]any{"indexName": indexName, "cardinality": cardinality}
//}
//
//// mulType 普通索引通过数据类型来进行筛选
//func (ms TableMeta) mulType(mulSelection map[string] /*indexType*/ []string /*indexName*/, i global.IndexMerge) any {
//	var ll = make(map[string][]int)
//	for _, v := range mulSelection {
//		for _, v1 := range v {
//			ll[v1] = ms.typeSelection(i.IndexColumn[v1])
//		}
//	}
//	return ll
//}
//func (ms TableMeta) keyChoiceDispos(i global.IndexMerge) global.IndexSelection {
//	//候选索引,先选择主键索引且索引列小于3，然后是唯一索引、普通索引
//	var (
//		candidateIndex                                             = map[string][]string{"pri": {}, "uni": {}, "mui": {}}
//		cardinalityGather                                          []any
//		maxCardinalityValue                                        uint64
//		cardinalityMaxGather                                       = make(map[string]uint64)
//		optimalIndexColumnType                                     []string
//		multipleMaxCardinalityGather                               map[string] /*索引名*/ []int //类型定义值
//		priSingleSelection, uniSingleSelection, muiSingleSelection = make(map[string][]string), make(map[string][]string), make(map[string][]string)
//		priMulleSelection, uniMulleSelection, muiMulleSelection    = make(map[string][]string), make(map[string][]string), make(map[string][]string)
//	)
//	for k, v := range i.IndexType {
//		for _, v1 := range []string{"pri", "uni", "mul"} {
//			if strings.EqualFold(v1, v) {
//				if len(i.IndexColumn[k]) > 0 {
//					candidateIndex[v1] = append(candidateIndex[v1], k)
//				}
//			}
//		}
//	}
//	//没有索引则退出
//	exit := true
//	for _, v := range candidateIndex {
//		if len(v) > 0 {
//			exit = false
//		}
//	}
//	if exit {
//		return global.IndexSelection{}
//	}
//	//筛选主键或者唯一索引为单列的
//	for k, v := range candidateIndex {
//		var fp, fu, fm []string
//		var mp, mu, mm []string
//		for _, v1 := range v {
//			if v2, ok := i.IndexColumn[v1]; ok {
//				if len(v2) == 1 {
//					if strings.EqualFold(k, "pri") {
//						fp = append(fp, v1)
//					} else if strings.EqualFold(k, "uni") {
//						fu = append(fu, v1)
//					} else if strings.EqualFold(k, "mul") {
//						fm = append(fm, v1)
//					}
//				} else {
//					if strings.EqualFold(k, "pri") {
//						mp = append(mp, v1)
//					} else if strings.EqualFold(k, "uni") {
//						mu = append(mu, v1)
//					} else if strings.EqualFold(k, "mul") {
//						mm = append(mm, v1)
//					}
//				}
//			}
//		}
//		if len(fp) > 0 {
//			priSingleSelection[k] = fp
//		}
//		if len(fu) > 0 {
//			uniSingleSelection[k] = fu
//		}
//		if len(fm) > 0 {
//			muiSingleSelection[k] = fm
//		}
//		if len(mp) > 0 {
//			priMulleSelection[k] = mp
//		}
//		if len(mu) > 0 {
//			uniMulleSelection[k] = mu
//		}
//		if len(mm) > 0 {
//			muiMulleSelection[k] = mm
//		}
//	}
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(priSingleSelection, i))
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(priMulleSelection, i))
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(uniSingleSelection, i))
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(uniMulleSelection, i))
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(muiSingleSelection, i))
//	cardinalityGather = append(cardinalityGather, ms.mulCardinality(muiMulleSelection, i))
//	for _, v := range cardinalityGather {
//		if v == nil {
//			continue
//		}
//		curryCardinalityValue := v.(map[string]any)["cardinality"].(uint64)
//		curryIndexName := fmt.Sprintf("%v", v.(map[string]any)["indexName"])
//		if curryCardinalityValue > maxCardinalityValue {
//			cardinalityMaxGather = map[string]uint64{
//				curryIndexName: curryCardinalityValue,
//			}
//			maxCardinalityValue = curryCardinalityValue
//		} else if curryCardinalityValue == maxCardinalityValue {
//			cardinalityMaxGather[curryIndexName] = curryCardinalityValue
//		}
//	}
//	//处理多个离散度相同的索引名
//	multipleMaxCardinalityGather = make(map[string][]int)
//	for k := range cardinalityMaxGather {
//		if v1, ok := i.IndexColumn[k]; ok {
//			multipleMaxCardinalityGather[k] = ms.typeSelection(v1)
//		}
//	}
//	//按照数据类型规则找到最优的
//	optimalIndexName := ms.typeSum(multipleMaxCardinalityGather)
//	for _, v := range i.IndexColumn[optimalIndexName] {
//		optimalIndexColumnType = append(optimalIndexColumnType, v.ColumnType)
//	}
//	return global.IndexSelection{
//		IndexType:        i.IndexType[optimalIndexName],
//		IndexColumn:      i.IndexColumn[optimalIndexName],
//		IndexName:        optimalIndexName,
//		IndexCardinality: cardinalityMaxGather[optimalIndexName],
//		IndexColumnType:  optimalIndexColumnType,
//	}
//}
//
//func (ms TableMeta) TableIndexMerge(queryData []global.IndexColumn, logThreadSeq int64) global.IndexMerge {
//	var (
//		event       = "[TableIndexMerge]"
//		execTimeout int64
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	vlog = fmt.Sprintf("(%d) %v %v Start index merging of table %v.%v", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//	if len(queryData) == 0 {
//		return global.IndexMerge{}
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, "no sql", execTimeout)
//	global.Wlog.Debug(vlog)
//	//索引列处理，联合索引进行列合并
//	//去除主键索引列、唯一索引列、普通索引列的所有列明
//	s := ms.indexNameColumnMerge(queryData, logThreadSeq)
//	vlog = fmt.Sprintf("(%d) %v %v Index merging of table %v.%v is completed. result is {%v}", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table, s)
//	global.Wlog.Debug(vlog)
//	return s
//}
//
//// indexNameColumnMerge 每个表的索引列数据信息合并及抽取
//func (ms TableMeta) indexNameColumnMerge(queryData []global.IndexColumn, _ int64) global.IndexMerge {
//	var indexName = make(map[string][]global.IndexColumn)
//	var indexType = make(map[string]string)
//	var indexColumnSeq = make(map[string][]string)
//	for _, v := range queryData {
//		if v1, ok := indexName[v.IndexName]; ok {
//			indexName[v.IndexName] = append(v1, v)
//		} else {
//			indexName[v.IndexName] = []global.IndexColumn{v}
//		}
//		if v1, ok := indexColumnSeq[v.IndexName]; ok {
//			indexColumnSeq[v.IndexName] = append(v1, v.ColumnSeq)
//		} else {
//			indexColumnSeq[v.IndexName] = []string{v.ColumnSeq}
//		}
//		if _, ok := indexType[v.IndexName]; !ok {
//			var tmpIndexType string
//			if v.NonUnique == "1" {
//				if v.ColumnKey == "1" {
//					tmpIndexType = "pri"
//				} else {
//					tmpIndexType = "uni"
//				}
//			} else {
//				tmpIndexType = "mul"
//			}
//			indexType[v.IndexName] = tmpIndexType
//		}
//	}
//	return global.IndexMerge{
//		Schema:         ms.Schema,
//		Table:          ms.Table,
//		IndexColumn:    indexName,
//		IndexType:      indexType,
//		IndexColumnSeq: indexColumnSeq,
//	}
//}
//
//func (ms TableMeta) TableIndexChoice(queryData []global.IndexColumn, logThreadSeq int64) global.IndexSelection {
//	var (
//		event       = "[TableIndexChoice]"
//		execTimeout int64
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	vlog = fmt.Sprintf("(%d) %v %v Start index choice of table %v.%v", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table)
//
//	if len(queryData) == 0 {
//		return global.IndexSelection{}
//	}
//	//索引列处理，联合索引进行列合并
//	//去除主键索引列、唯一索引列、普通索引列的所有列明
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", ms.LogThreadSeq, callFuncInfo, event, "no sql", execTimeout)
//	global.Wlog.Debug(vlog)
//	f1 := ms.TableIndexMerge(queryData, logThreadSeq)
//	if global.IsEmptyStruct(f1) {
//		return global.IndexSelection{}
//	}
//	s := ms.keyChoiceDispos(f1)
//	vlog = fmt.Sprintf("(%d) %v %v Index choice of table %v.%v is completed. result is {%v}", ms.LogThreadSeq, callFuncInfo, event, ms.Schema, ms.Table, s)
//	global.Wlog.Debug(vlog)
//	return s
//}
//
///*
//Trigger Oracle 查询触发器信息
//*/
//func (ms TableMeta) Trigger(db *sql.DB, logThreadSeq int64) (map[string]string, error) {
//	var (
//		tmpb                       = make(map[string]string)
//		triggerOn, triggerTRX      string
//		event                      = "[Trigger]"
//		execTimeout                int64
//		err                        error
//		triggerName, createTrigger []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//	vlog = fmt.Sprintf("(%d) %v %v Start to query the trigger information under the %s database.", logThreadSeq, callFuncInfo, event, DBType)
//	global.Wlog.Debug(vlog)
//	strsql := fmt.Sprintf("select TRIGGER_name as triggerName,TABLE_NAME as tableName from all_triggers where owner = '%s'", strings.ToUpper(ms.Schema))
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", logThreadSeq, callFuncInfo, event, strsql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		triggerName = f1.([]map[string]interface{})
//	}
//
//	for _, v := range triggerName {
//		strsql = fmt.Sprintf(" SELECT DBMS_METADATA.GET_DDL('TRIGGER','%s','%s') AS CREATE_TRIGGER FROM DUAL", v["TRIGGERNAME"], ms.Schema)
//		if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//			vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", logThreadSeq, callFuncInfo, event, strsql, err)
//			global.Wlog.Error(vlog)
//			return nil, err
//		}
//		vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//		global.Wlog.Debug(vlog)
//		if f1 != nil {
//			createTrigger = f1.([]map[string]interface{})
//		}
//		for _, b := range createTrigger {
//			c := strings.TrimSpace(strings.ReplaceAll(fmt.Sprintf("%s", b["CREATE_TRIGGER"]), "\n", " "))
//			d := strings.Join(strings.Fields(c), " ")
//			//获取trigger Name
//			onI := strings.Index(d, " ON ")
//			triNbeg, triNend := strings.Index(d[:onI], "\""), strings.LastIndexAny(d[:onI], "\"")
//			triggerN := d[triNbeg : triNend+1]
//			//获取trigger action
//			triggerAction := strings.TrimSpace(d[triNend+1 : onI])
//			//获取trigger 作用的表
//			if strings.Contains(d, "BEGIN") && strings.Contains(d, "END") {
//				e := d[onI+1 : strings.Index(d, "BEGIN")]
//				triActionTend := strings.Index(e, "FOR")
//				triActionTbeg := strings.Index(e, "ON")
//				triggerOn = strings.TrimSpace(e[triActionTbeg+2 : triActionTend])
//				if strings.Contains(triggerOn, "\"") {
//					triggerOn = strings.TrimSpace(strings.ReplaceAll(triggerOn, "\"", ""))
//				}
//				//触发器结构体  begin --> commit
//				begst := strings.Index(d, "BEGIN")
//				end := strings.Index(d, "END")
//				triggerTRX = strings.TrimSpace(strings.ReplaceAll(strings.ReplaceAll(strings.ToUpper(d[begst:end]), "COMMIT", ""), ";", ""))
//				if strings.Contains(triggerTRX, "\"") {
//					triggerTRX = strings.ReplaceAll(triggerTRX, "\"", "")
//				}
//			}
//			tmpb[triggerN] = fmt.Sprintf("%s %s %s", triggerAction, triggerOn, triggerTRX)
//		}
//	}
//	vlog = fmt.Sprintf("(%d) %v %v Complete the trigger information query. result is {%v}", logThreadSeq, callFuncInfo, event, tmpb)
//	global.Wlog.Debug(vlog)
//	return tmpb, nil
//}
//
///*
//Proc 存储过程校验
//*/
//func (ms TableMeta) Proc(db *sql.DB, logThreadSeq int64) (map[string]string, error) {
//	var (
//		tmpb                    = make(map[string]string)
//		execTimeout             int64
//		event                   = "[Proc]"
//		err                     error
//		routineName, createFunc []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) %v %v Start to query the stored procedure information under the %s database.", logThreadSeq, callFuncInfo, event, DBType)
//	global.Wlog.Debug(vlog)
//
//	strsql := fmt.Sprintf(" select object_name as ROUTINE_NAME from all_procedures where object_type='PROCEDURE' and owner = '%s'", ms.Schema)
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", logThreadSeq, callFuncInfo, event, strsql, err)
//		global.Wlog.Error(vlog)
//		return nil, err
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	if f1 != nil {
//		routineName = f1.([]map[string]interface{})
//	}
//	for _, v := range routineName {
//		strsql = fmt.Sprintf(" SELECT DBMS_METADATA.GET_DDL('PROCEDURE','%s','%s') AS CREATE_PROCEDURE FROM DUAL", v["ROUTINE_NAME"], ms.Schema)
//		if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//			vlog = fmt.Sprintf("(%d) %v %v The execution of a sql statement failed. sql is {%v},error is {%v}", logThreadSeq, callFuncInfo, event, strsql, err)
//			global.Wlog.Error(vlog)
//			return nil, err
//		}
//		vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//		global.Wlog.Debug(vlog)
//		if f1 != nil {
//			routineName = f1.([]map[string]interface{})
//		}
//		for _, b := range createFunc {
//			tmpb[strings.ToUpper(fmt.Sprintf("%s", v["ROUTINE_NAME"]))] = strings.ReplaceAll(fmt.Sprintf("%s", b["CREATE_PROCEDURE"]), "\n", "")
//		}
//		vlog = fmt.Sprintf("(%d) Oracle DB query databases %s Stored Procedure data completion...", logThreadSeq, ms.Schema)
//		global.Wlog.Debug(vlog)
//	}
//	vlog = fmt.Sprintf("(%d) %v %v Complete the stored procedure information query. result is {%v}", logThreadSeq, callFuncInfo, event, tmpb)
//	global.Wlog.Debug(vlog)
//	return tmpb, nil
//}
//
///*
//Func Oracle 存储函数或自定义函数校验
//*/
//func (ms TableMeta) Func(db *sql.DB, logThreadSeq int64) (map[string]string, error) {
//	var (
//		tmpb                    = make(map[string]string)
//		event                   = "Q_Proc"
//		execTimeout             int64
//		err                     error
//		routineName, createFunc []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) [%s] Start to query the stored Func information under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//	strsql := fmt.Sprintf("select OBJECT_NAME as ROUTINE_NAME  from all_procedures where object_type='FUNCTION' and owner = '%s'", ms.Schema)
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		return nil, err
//	}
//	if f1 != nil {
//		routineName = f1.([]map[string]interface{})
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	for _, v := range routineName {
//		strsql = fmt.Sprintf(" SELECT DBMS_METADATA.GET_DDL('FUNCTION','%s','%s') AS CREATE_FUNCTION FROM DUAL", v["ROUTINE_NAME"], ms.Schema)
//		if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//			return nil, err
//		}
//		if f1 != nil {
//			createFunc = f1.([]map[string]interface{})
//		}
//		for _, b := range createFunc {
//			d := strings.Join(strings.Fields(strings.ReplaceAll(fmt.Sprintf("%s", b["CREATE_FUNCTION"]), "\n", " ")), " ")
//			if strings.Contains(strings.ToUpper(d), "BEGIN") && strings.Contains(strings.ToUpper(d), "END") {
//				strings.Index(d, "BEGIN")
//			}
//			tmpb[strings.ToUpper(fmt.Sprintf("%s", v["ROUTINE_NAME"]))] = strings.ReplaceAll(fmt.Sprintf("%s", b["CREATE_FUNCTION"]), "\n", "")
//		}
//	}
//	vlog = fmt.Sprintf("(%d) [%s] Complete the stored Func information query under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//	return tmpb, nil
//}
//
///*
//Foreign Oracle 外键检查
//*/
//func (ms TableMeta) Foreign(db *sql.DB, logThreadSeq int64) (map[string]string, error) {
//	var (
//		routineNameM               = make(map[string]int)
//		tmpb                       = make(map[string]string)
//		event                      = "Q_Foreign"
//		execTimeout                int64
//		err                        error
//		foreignName, createForeign []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) [%s] Start to query the Foreign information under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//
//	strsql := fmt.Sprintf(" select c.OWNER as DATABASE,c.table_name as TABLENAME, c.r_constraint_name,c.delete_rule,cc.column_name,cc.position from user_constraints c join user_cons_columns cc on c.constraint_name=cc.constraint_name and c.table_name=cc.table_name  where c.constraint_type='R' and c.validated='VALIDATED' and c.OWNER = '%s' and c.table_name='%s'", ms.Schema, ms.Table)
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		return nil, err
//	}
//	if f1 != nil {
//		foreignName = f1.([]map[string]interface{})
//	}
//
//	for _, v := range foreignName {
//		routineNameM[fmt.Sprintf("%s.%s", v["DATABASE"], v["TABLENAME"])]++
//	}
//	for k := range routineNameM {
//		schema, table := strings.Split(k, ".")[0], strings.Split(k, ".")[1]
//		strsql = fmt.Sprintf("SELECT DBMS_METADATA.GET_DDL('TABLE','%s','%s') as CREATE_FOREIGN FROM DUAL", table, schema)
//		if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//			return nil, err
//		}
//		if f1 != nil {
//			createForeign = f1.([]map[string]interface{})
//		}
//		for _, b := range createForeign {
//			var p, q, o string
//			d := fmt.Sprintf("%s", b["CREATE_FOREIGN"])
//			f := strings.Split(d, "\n")
//			for _, g := range f {
//				if strings.Contains(g, "CONSTRAINT") {
//					p = strings.TrimSpace(g)
//				}
//				if strings.Contains(g, "REFERENCES") {
//					q = strings.TrimSpace(g)
//				}
//			}
//			if strings.Contains(p, "CONSTRAINT") && strings.Contains(p, "REFERENCES") {
//				o = p
//			}
//			if strings.HasPrefix(q, "REFERENCES") {
//				o = strings.ReplaceAll(fmt.Sprintf("%s %s", p, q), " ENABLE", "")
//			}
//			tmpb[k] = strings.ToUpper(strings.ReplaceAll(o, "\"", "!"))
//		}
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	vlog = fmt.Sprintf("(%d) [%s] Complete the Foreign information query under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//	return tmpb, nil
//}
//
///*
//Partitions 分区表校验
//*/
//func (ms TableMeta) Partitions(db *sql.DB, logThreadSeq int64) (map[string]string, error) {
//	var (
//		routineNameM                     = make(map[string]int)
//		tmpb                             = make(map[string]string)
//		event                            = "Q_Partitions"
//		execTimeout                      int64
//		err                              error
//		partitionsName, createPartitions []map[string]interface{}
//	)
//	pc, _, _, _ := runtime.Caller(1)
//	callingFunc := runtime.FuncForPC(pc)
//	callFile, callLine := callingFunc.FileLine(pc)
//	callFunc := callingFunc.Name()
//	callFuncInfo := fmt.Sprintf("Call functions %v Call File %v:%v", callFunc, callFile, callLine)
//
//	vlog = fmt.Sprintf("(%d) [%s] Start to query the Partitions information under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//	strsql := fmt.Sprintf("select OWNER,TABLE_NAME from all_tables  where owner='%s' and TABLE_NAME='%s' and partitioned='YES'", ms.Schema, ms.Table)
//	dispos := dataDispos.InstanceActiveS{DBType: DBType, DB: db, StopTime: ms.SqlExecStopTime}
//	var f1 any
//	if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//		return nil, err
//	}
//	if f1 != nil {
//		partitionsName = f1.([]map[string]interface{})
//	}
//	vlog = fmt.Sprintf("(%d) %v %v A sql statement was executed successfully. sql is {%v}, exec timeout is {%vms}", logThreadSeq, callFuncInfo, event, strsql, execTimeout)
//	global.Wlog.Debug(vlog)
//	for _, v := range partitionsName {
//		routineNameM[fmt.Sprintf("%s.%s", v["OWNER"], v["TABLE_NAME"])]++
//	}
//	for k := range routineNameM {
//		var zi string
//		if strings.EqualFold(k, fmt.Sprintf("%s.%s", ms.Schema, ms.Table)) {
//			zi = fmt.Sprintf("%s.%s", ms.Schema, ms.Table)
//		} else {
//			zi = k
//		}
//		schema, table := strings.Split(k, ".")[0], strings.Split(k, ".")[1]
//		strsql = fmt.Sprintf("SELECT DBMS_METADATA.GET_DDL('TABLE','%s','%s') AS CREATE_PARTITIONS FROM DUAL", table, schema)
//		if execTimeout, f1, err = dispos.SqlQuery(strsql, "sMap"); err != nil {
//			return nil, err
//		}
//		if f1 != nil {
//			createPartitions = f1.([]map[string]interface{})
//		}
//		for _, b := range createPartitions {
//			z := strings.Split(fmt.Sprintf("%s", b["CREATE_PARTITIONS"]), "\n")
//			var a, c []string
//			var partitionMode, partitionColumn string
//			for _, bi := range z {
//				if strings.Contains(bi, " PARTITION BY ") {
//					ii := strings.TrimSpace(strings.ReplaceAll(bi, " PARTITION BY ", ""))
//					partitionMode, partitionColumn = strings.Split(ii, " ")[0], strings.ReplaceAll(strings.Split(ii, " ")[1], "\"", "")
//					c = append(c, fmt.Sprintf(" PARTITION BY %s %s", partitionMode, strings.ToUpper(partitionColumn)))
//				}
//				if strings.Contains(bi, "SUBPARTITION BY ") || strings.Contains(bi, "SUBPARTITIONS ") {
//					c = append(c, strings.ToUpper(strings.TrimSpace(bi)))
//				}
//				if strings.Contains(bi, "PARTITION ") && strings.Contains(bi, "VALUES ") {
//					bi = strings.ReplaceAll(bi, "\"", "")
//					c = append(c, fmt.Sprintf(" %s,", strings.TrimSpace(bi)))
//				}
//				if strings.Contains(bi, "PARTITION \"") {
//					c = append(c, bi)
//				}
//			}
//			x := fmt.Sprintf("%s %s);", strings.Join(a, ""), strings.Join(c, "")[:len(strings.Join(c, ""))-1])
//			xs := strings.Join(strings.Fields(x), " ")
//
//			if strings.ToUpper(partitionMode) == "HASH" {
//				ad := strings.Split(strings.ReplaceAll(strings.Split(xs, ") ")[1], "PARTITION ", ""), " ")
//				xs = fmt.Sprintf("PARTITION BY %s %s PARTITIONS %d);", partitionMode, partitionColumn, len(ad))
//			}
//			tmpb[zi] = strings.ReplaceAll(xs, "\"", "!")
//		}
//	}
//	vlog = fmt.Sprintf("(%d) [%s] Complete the Partitions information query under the %s database.", logThreadSeq, event, DBType)
//	global.Wlog.Debug(vlog)
//	return tmpb, nil
//}
//func (ms TableMeta) Struct(_ *sql.DB) (map[string]string, error) {
//	return nil, nil
//}
